package com.penta.services;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.penta.entity.HeadInfoVO;
import com.penta.helper.CellStyleBuilder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFPicture;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 定义一个抽象类
 */
public abstract class ModuleService {

    /**
     * 生成1的 writer
     */
    ExcelWriter writer1;

    /**
     * 生成2
     */
    ExcelWriter writer2;

    List<List<Object>> dataList;

    List<byte[]> pictureDataList;

    public ModuleService() {

    }

    FormulaEvaluator writer1Eval;     // writer1的计算句柄
    FormulaEvaluator writer2Eval;     // writer2的计算句柄

    public ModuleService(ExcelWriter writer1,ExcelWriter writer2,List<List<Object>> dataList,List<byte[]> pictureDataList) {
        this.writer1 = writer1;
        this.writer2 = writer2;
        this.dataList = dataList;
        this.pictureDataList = pictureDataList;
        this.writer1Eval = writer1.getWorkbook().getCreationHelper().createFormulaEvaluator();    // 计算句柄
        this.writer2Eval = writer2.getWorkbook().getCreationHelper().createFormulaEvaluator();    // 计算句柄
    }

    /**
     * 定义抽象方法，用于获取表头的内容
     * @return
     */
    abstract HeadInfoVO getHeadInfoByDataList();

    /**
     * 定义抽象方法，用于输出操作
     */
    abstract void execOutput();

    /**
     * 获取内容，从列表
     * @param dataList
     * @param x
     * @param y
     * @return
     */
    public String getContentFromDataList(List<List<Object>> dataList,int x,int y) {
        if(CollectionUtil.isEmpty(dataList)) {
            return null;
        }

        List<Object> contentDataList = dataList.get(x);
        String content = null;
        try {
            content = String.valueOf(contentDataList.get(y));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * 写入数据到文档中
     * @param writer
     * @param x
     *          行码
     * @param y
     *          列码
     * @param content
     *          内容
     */
    public void writeContent(ExcelWriter writer, int x, int y, String content, CellStyle cellStyle) {

        Sheet sheet = writer.getSheet();
        Row row = sheet.getRow(x);
        if(ObjectUtil.isEmpty(row)) {
            row = sheet.createRow(x);
        }
        Cell rowCell = row.getCell(y,Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
        if(ObjectUtil.isEmpty(rowCell)) {
            rowCell = row.createCell(y);
        }

        /**
         * 如果传入了样式
         */
        if(ObjectUtil.isNotEmpty(cellStyle)) {
            rowCell.setCellStyle(cellStyle);
        }

        rowCell.setCellValue(content);
    }


    /**
     * 根据装运港信息，获取港口与集装箱类型
     *          Port of Loading: FOSHAN, China
     *          Ship to: TANZ
     *          Payment: 20% deposit, 80% against B/L copy.
     *          Transport:  2X40'HQ  by sea shipment
     *          Delivery Date: 30days after deposit
     *
     * @param partLoading
     * @return
     */
    public static Map<String,String> getPortAndTypeMapByPartLoading(String partLoading) {
        Map<String,String> map = new HashMap<>();
        if(StrUtil.isBlank(partLoading)) {
            return map;
        }

        /**
         * 取出港口
         */
        String port = null;
        String regexForPort = "Port of Loading:\\s*([^\\n]+)";
        Pattern patternForPort = Pattern.compile(regexForPort);
        Matcher matcherForPort = patternForPort.matcher(partLoading);
        if(matcherForPort.find()) {
            port = matcherForPort.group(1);
            port = StrUtil.replace(port," China","");
            port = StrUtil.replace(port," china","");
            port = StrUtil.replace(port,"China","");
            port = StrUtil.replace(port,"china","");
            port = StrUtil.replace(port,",","");
            port = StrUtil.replace(port,"，","");
        }

        /**
         * 取出集装箱信息
         */
        String type = null;
        String regexForType = "Transport:\\s+([^\\s]+)(?=\\s+by)";
        Pattern patternForType = Pattern.compile(regexForType);
        Matcher matcherForType = patternForType.matcher(partLoading);
        if(matcherForType.find()) {
            type = matcherForType.group(1);
        }

        /**
         * 取出：出港口
         */
        String shipTo = null;
        String regexForShipTo = "Ship to:\\s*([^\\\\n]+)";
        Pattern patternForShipTo = Pattern.compile(regexForShipTo);
        Matcher matcherForShipTo = patternForShipTo.matcher(partLoading);
        if(matcherForShipTo.find()) {
            shipTo = matcherForShipTo.group(1);
        }
        if(StrUtil.isNotBlank(shipTo)) {
            shipTo = shipTo.toLowerCase();        // 转为小写
        }

        map.put("port",port);
        map.put("type",type);
        map.put("shipTo",shipTo);    // 出港口
        return map;
    }

    /**
     * 获取供应商列表
     *
     * @param dataList
     * @return
     */
    public static String getSupplierFromDataList(List<List<Object>> dataList) {

        String supplierContent = null;
        try {
            supplierContent = dataList.stream().map(dataObj->{
                if(dataObj.size()<4) {
                    return null;
                }
                return StrUtil.trim(String.valueOf(dataObj.get(3)));
            }).filter(content->{
                if(StrUtil.startWith(content,"TOTAL")) {
                    return false;
                }
                return StrUtil.containsAny(content,"TOTAL");
            }).map(content->{
                String[] splitContent = content.split("TOTAL");
                String supplier = StrUtil.trim(splitContent[0]);

                // String supplier = StrUtil.trim(content.split("\\s+")[0]);
                // supplier = supplier.replaceAll("[^A-Za-z]","");
                return supplier;
            }).collect(Collectors.joining("+"));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return supplierContent;
    }


    /**
     * 取出物品列表，一个文档可能有多条物品列表
     * @param dataList
     * @return
     */
    public static List<Map<String,Object>> getMaterialListFromDataList(List<List<Object>> dataList,List<byte[]> pictureDataList) {

        List<Map<String,Object>> list = new ArrayList<>();

        List<Object> currMaterialList = new ArrayList<>();
        boolean orgListStatus = false;    // 是否正在组织列表的状态，false 表示没有在组织
        boolean colorWithPhoto = false;    // 当前供应商的货是否带图片
        int j = 0;       // 产品图片、颜色图片 索引
        for (int i = 0; i < dataList.size(); i++) {
            List<Object> objects = dataList.get(i);    // 取出一条数据
            String column0Value = String.valueOf(objects.get(0));         // 查看当前第0列的数据
            if("1".equals(column0Value)) {
                orgListStatus = true;            // 表示正在构建列表中

                /**
                 * 这里是1的开始，即是前一行，就是标题，我们需要获取第5列（索引值为4），查看颜色是否有图片
                 */
                List<Object> titleRow = dataList.get(i - 1);    // 标题行
                String colorTitleContent = String.valueOf(titleRow.get(4));     // 颜色标题栏的内容
                if(StrUtil.isNotBlank(colorTitleContent)) {
                    String colorTitleContentToLowerCase = colorTitleContent.toLowerCase();     // 转为小写
                    if(StrUtil.containsAny(colorTitleContentToLowerCase," with ")) {
                        colorWithPhoto = true;
                    }
                }

                byte[] itemPhotoByteArr = getPicture(pictureDataList,j);     // 取出产品图片
                objects.add(itemPhotoByteArr);      // 添加产品图片
                j += 1;
                if(colorWithPhoto) {     // 如果颜色有图片
                    byte[] colorPhotoByteArr = pictureDataList.get(j);    // 取出颜色图片
                    objects.add(colorPhotoByteArr);    // 添加颜色图片
                    j += 1;
                }

                currMaterialList.add(objects);

            } else if(orgListStatus && StrUtil.isNumeric(column0Value)) {      // 如果也数字，表示是同一组的
                byte[] itemPhotoByteArr = getPicture(pictureDataList,j);     // 取出产品图片
                objects.add(itemPhotoByteArr);      // 添加产品图片
                j += 1;
                if(colorWithPhoto) {     // 如果颜色有图片
                    byte[] colorPhotoByteArr = pictureDataList.get(j);    // 取出颜色图片
                    objects.add(colorPhotoByteArr);    // 添加颜色图片
                    j += 1;
                }
                currMaterialList.add(objects);
            }

            if(orgListStatus && StrUtil.isNotBlank(column0Value) && StrUtil.containsAny(column0Value,"TOTAL")) {     // 如果在组织列表时，且第0行数据增加

                orgListStatus = false;

                //String supplierTotal = String.valueOf(objects.get(5));   //// 这这里就可能是 XXX TOTAL 的内容
                if(StrUtil.containsAny(column0Value,"TOTAL")) {
                    // 取出供应商
                    String supplier = StrUtil.trim(column0Value.split("TOTAL")[0]);
                    //String supplier = StrUtil.trim(column0Value.split("\\s+")[0]);
                    //supplier = supplier.replaceAll("[^A-Za-z]","");

                    // 新建列表并复制，并将原来的列表清空
                    List<Object> newList = currMaterialList.stream().collect(Collectors.toList());
                    currMaterialList = new ArrayList<>();

                    Map<String,Object> map = new HashMap<>();
                    map.put("supplierName",supplier);
                    map.put("dataList",newList);
                    map.put("colorWithPhoto",colorWithPhoto);    // 是否带图片
                    list.add(map);
                }
                colorWithPhoto = false;              // 重新置为 false
            }

        }

        return list;
    }

    /**
     * 根据索引，获取图片
     *
     * @param pictureList
     * @param index
     * @return
     */
    public static byte[] getPicture(List<byte[]> pictureList,int index) {

        if(CollectionUtil.isEmpty(pictureList)) {
            return null;
        }

        if(index >= 0 && index < pictureList.size()) {
            return pictureList.get(index);
        }
        return null;
    }

    /**
     * 写入空行
     * @param flag
     *          标识符：
     *              0：整行都不加边框
     *              1：上边框加边框
     *              3：下边框加边框
     */
    public static void writerBlankRow(ExcelWriter writer,List<String> blankRow,int currRowIndex,String flag) {
        writer.writeRow(blankRow);
        Row currRow = writer.getSheet().getRow(currRowIndex);
        if(currRow == null) {
            currRow = writer.getSheet().createRow(currRowIndex);
        }
        if("0".equals(flag)) {
            for(int i=0; i< blankRow.size();i++) {
                Cell currCell = currRow.getCell(i);
                if(currCell == null) {
                    currCell = currRow.createCell(i);
                }
                currCell.setCellStyle(new CellStyleBuilder(writer).setCellBorder("0").setFillBackgroundColor(1).setFillForegroundColor(1).build());
            }
        } else if("1".equals(flag)) {
            for(int i=0; i< blankRow.size();i++) {
                Cell currCell = currRow.getCell(i);
                if(currCell == null) {
                    currCell = currRow.createCell(i);
                }
                currCell.setCellStyle(new CellStyleBuilder(writer).setCellBorder("1").setFillBackgroundColor(1).setFillForegroundColor(1).build());
            }
        } else if("3".equals(flag)) {
            for(int i=0; i< blankRow.size();i++) {
                Cell currCell = currRow.getCell(i);
                if(currCell == null) {
                    currCell = currRow.createCell(i);
                }
                currCell.setCellStyle(new CellStyleBuilder(writer).setCellBorder("3").setFillBackgroundColor(1).setFillForegroundColor(1).build());
            }
        }
    }

}
